package com.unlcn.ils.wms.backend.webservice.client;

import cn.huiyunche.commons.exception.BusinessException;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.unlcn.ils.wms.backend.enums.InboundOrderBusinessTypeEnum;
import com.unlcn.ils.wms.backend.enums.SendStatusEnum;
import com.unlcn.ils.wms.backend.service.webservice.client.WmsJmDcsService;
import com.unlcn.ils.wms.backend.service.webservice.client.enums.WmsWebserviceInterfaceEnum;
import com.unlcn.ils.wms.backend.service.webservice.client.enums.WmsWebserviceReceiverAndSenderEnum;
import com.unlcn.ils.wms.backend.util.webservice.WebServiceSoapUtils;
import com.unlcn.ils.wms.backend.util.webservice.XmlParseUtils;
import com.unlcn.ils.wms.base.mapper.junmadcs.*;
import com.unlcn.ils.wms.base.model.junmadcs.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * wms和君马dcs接口调用业务
 */
@Service
public class WmsJmDcsServiceImpl implements WmsJmDcsService {
    private Logger LOGGER = LoggerFactory.getLogger(WmsJmDcsServiceImpl.class);


    private static final int TOTAL_COUNT = 5;

    @Value("${wms.webservice.dcs.host.url}")
    private String dcsHost;
    @Value("${wms.webservice.username}")
    private String username;
    @Value("${wms.webservice.password}")
    private String password;


    @Autowired
    private WmsOutOfStorageMapper wmsOutOfStorageMapper;

    @Autowired
    private WmsHandoverOrderMapper wmsHandoverOrderMapper;

    @Autowired
    private WmsShipmentPlanCancelMapper wmsShipmentPlanCancelMapper;

    @Autowired
    private WmsOutOfStorageExcpMapper wmsOutOfStorageExcpMapper;

    @Autowired
    private WmsHandoverOrderExcpMapper wmsHandoverOrderExcpMapper;

    @Autowired
    private WmsShipmentCancelExcpMapper wmsShipmentCancelExcpMapper;

    @Autowired
    private WmsDcsLogMapper wmsDcsLogMapper;

    /**
     * 入库接口(公用)  测试地址http://58.144.142.90:50000/dir/wsdl?p=sa/4765dc60a4143d139ca4e7afed745ffe
     *
     * @param wmsOutOfStorageList 接口表列表
     * @throws Exception 异常
     */
    @Override
    public void updateSendInOrOutboundRequest(List<WmsOutOfStorage> wmsOutOfStorageList) throws Exception {
        LOGGER.info("WmsJmDcsServiceImpl.updateSendInOrOutboundRequest param{}", wmsOutOfStorageList);
        //加入spring的上下文
        //SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if (CollectionUtils.isEmpty(wmsOutOfStorageList)) {
            throw new BusinessException("传入的调用dcs接口入库数据为空!");
        }
        StringBuilder soapXmlBuf = new StringBuilder();
        //xml头
        soapXmlBuf.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ext=\"http://externalInterface.dms.infodms.com\" xmlns:beam=\"http://beam.externalInterface.dms.infodms.com\">")
                .append("<soapenv:Header/>")
                .append("<soapenv:Body>")
                .append("<ext:excuteService>")
                .append("<ext:pos>")
                .append("<beam:dmsHeader>")
                .append("<beam:BUSID>" + wmsOutOfStorageList.get(0).getDataId() + "</beam:BUSID>")//业务id
                .append("<beam:DTSEND>" + sdf.format(new Date()) + "</beam:DTSEND>")//发送时间
                .append("<beam:FREEUSE>" + "" + "</beam:FREEUSE>")//备用字段
                .append("<beam:MSGID>" + wmsOutOfStorageList.get(0).getDataId() + "</beam:MSGID>")//消息id
                .append("<beam:RECEIVER>" + WmsWebserviceReceiverAndSenderEnum.RECEIVER_DCS.getText() + "</beam:RECEIVER>")//接收
                .append("<beam:SENDER>" + WmsWebserviceReceiverAndSenderEnum.SENDER.getText() + "</beam:SENDER>")//发送方
                .append("<beam:TLGID>" + WmsWebserviceInterfaceEnum.INBOUND_OUT_DCS.getValue() + "</beam:TLGID>")//接口id
                .append("<beam:TLGNAME>" + WmsWebserviceInterfaceEnum.INBOUND_OUT_DCS.getText() + "</beam:TLGNAME>")//接口名称
                .append("</beam:dmsHeader>")
                .append("<beam:values>");
        //2018-2-6 增加物料编码
        ArrayList<Long> dataIds = Lists.newArrayList();//用此id进行更新
        for (WmsOutOfStorage wmsOutOfStorage : wmsOutOfStorageList) {
            dataIds.add(wmsOutOfStorage.getDataId());
            if (InboundOrderBusinessTypeEnum.Z2.getCode().equals(wmsOutOfStorage.getZtype())
                    && StringUtils.isBlank(wmsOutOfStorage.getMblnr())) {
                throw new BusinessException("调拨单号为空!");
            }
            if (StringUtils.isBlank(wmsOutOfStorage.getZaction())) {
                throw new BusinessException("出入库类型为空!");
            }
            if (StringUtils.isBlank(wmsOutOfStorage.getZtype())) {
                throw new BusinessException("业务类型为空!");
            }
            if (Objects.equals(wmsOutOfStorage.getBldat(), null)) {
                throw new BusinessException("出入库日期为空!");
            }
            if (StringUtils.isBlank(wmsOutOfStorage.getSernr())) {
                throw new BusinessException("出入库车架号为空!");
            }
            soapXmlBuf.append("<ext:item>")
                    .append("<beam:BUSS_NO>" + wmsOutOfStorage.getMblnr() + "</beam:BUSS_NO>")//调拨单号
                    .append("<beam:FREEUSE1>" + "" + "</beam:FREEUSE1>\n")//备用
                    .append("<beam:FREEUSE2>" + "" + "</beam:FREEUSE2>\n")//备用
                    .append("<beam:FREEUSE3>" + "" + "</beam:FREEUSE3>\n")//备用
                    .append("<beam:FREEUSE4>" + "" + "</beam:FREEUSE4>\n")//备用
                    .append("<beam:FREEUSE5>" + "" + "</beam:FREEUSE5>\n")//备用
                    .append("<beam:IN_OUT_TYPE>" + wmsOutOfStorage.getZaction() + "</beam:IN_OUT_TYPE>")//出入库类型
                    .append("<beam:IS_SPECIAL_CAR>" + wmsOutOfStorage.getZtflag() + "</beam:IS_SPECIAL_CAR>")
                    .append("<beam:REMARK>" + (StringUtils.isBlank(wmsOutOfStorage.getZdemo()) ? "" : wmsOutOfStorage.getZdemo()) + "</beam:REMARK>")
                    .append("<beam:STORAGE_TIME>" + sdf.format(wmsOutOfStorage.getBldat()) + "</beam:STORAGE_TIME>")//出入库日期
                    .append("<beam:STORAGE_TYPE>" + wmsOutOfStorage.getZtype() + "</beam:STORAGE_TYPE>")//业务类型
                    .append("<beam:VIN>" + wmsOutOfStorage.getSernr() + "</beam:VIN>")
                    .append("<beam:MATERIAL_CODE>" + wmsOutOfStorage.getMatnr() + "</beam:MATERIAL_CODE>")
                    .append("<beam:WH_NAME>" + wmsOutOfStorage.getUmlgo() + "</beam:WH_NAME>")
                    .append("</ext:item>");
        }
        soapXmlBuf.append("</beam:values>")
                .append("</ext:pos>")
                .append("</ext:excuteService>")
                .append("</soapenv:Body>")
                .append("</soapenv:Envelope>");
        String soapUrl = "http://" + dcsHost + "/XISOAPAdapter/MessageServlet?senderParty=&senderService=BC_WMS&receiverParty=&receiverService=&interface=SI_WMS2ALL_VehicleStorageImport_OUT&interfaceNamespace=http://zjunma.com/TRAUM/WMS/ALL";
        String soapHost = dcsHost;
        String soapAction = "http://sap.com/xi/WebService/soap/1.1";
        System.err.println(soapXmlBuf.toString());
        LOGGER.info("出入库调用dcs接口参数:", soapXmlBuf.toString());
        String result = WebServiceSoapUtils.postSoapToPi(soapUrl, soapHost, soapXmlBuf.toString(), soapAction, username, password);
        //转义返回的字符串
        String xmlResult = StringEscapeUtils.unescapeHtml3(result);
        LOGGER.info("出入库调用dcs接口结果:", xmlResult);
        System.out.println(xmlResult);
        //记录日志
        String finalXmlResult = xmlResult;
        Runnable runnable = () -> {
            WmsDcsLogWithBLOBs log = new WmsDcsLogWithBLOBs();
            log.setParam(soapXmlBuf.toString());
            log.setMsgHead(null);
            log.setSendType("OUT");
            log.setMsgBody(finalXmlResult);
            log.setGmtCreate(new Date());
            log.setGmtUpdate(new Date());
            log.setUrl("WmsJmDcsServiceImpl.updateSendInOrOutboundRequest");
            wmsDcsLogMapper.insertSelective(log);
            LOGGER.info("WmsJmDcsServiceImpl.updateSendInOrOutboundRequest  保存dcs出入库发送dcs日志成功");
        };
        new Thread(runnable).start();

        //解析xml
        if (StringUtils.isNotBlank(xmlResult)) {
            int startIndex = xmlResult.lastIndexOf("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
            int lastIndex = xmlResult.lastIndexOf("</ns0:excuteServiceReturn></ns0:excuteServiceResponse></SOAP:Body></SOAP:Envelope>");
            if (!Objects.equals(startIndex, -1) && !Objects.equals(lastIndex, -1)) {
                xmlResult = xmlResult.substring(startIndex, lastIndex);
                Map<String, Object> objectMap = XmlParseUtils.xml2map(xmlResult);
                //获取返回结果
                String json = new Gson().toJson(objectMap);
                JSONObject jsonObject3 = JSONObject.parseObject(json);
                String code_str = jsonObject3.getString("returnCode");
                JSONObject jsonObject4 = JSONObject.parseObject(code_str);
                String returnCode_str = jsonObject4.getString("returnCode");
                if (StringUtils.isNotBlank(returnCode_str)) {
                    if ("E".equals(returnCode_str)) {
                        //错误
                        String error_str = jsonObject3.getString("errorDetails");
                        if (StringUtils.isNotBlank(error_str)) {
                            if (!error_str.startsWith("[")) {
                                error_str = "[" + error_str + "]";
                            }
                            JSONArray jsonArray = JSONArray.parseArray(error_str);
                            for (Object o : jsonArray) {
                                JSONObject jsonObject6 = JSONObject.parseObject(o.toString());
                                String em_str = jsonObject6.getString("eMsg");
                                JSONObject jsonObject7 = JSONObject.parseObject(em_str);
                                String emsg = jsonObject7.getString("eMsg");//错误日志
                                String vin_str = jsonObject6.getString("VIN");
                                JSONObject jsonObject8 = JSONObject.parseObject(vin_str);
                                String vin = jsonObject8.getString("VIN");//车架号
                                //更新出入库单接口表中数据及接口异常表中数据--只返回了失败的数据所以只更改该车为异常
                                WmsOutOfStorageExample dcsStorageExample = new WmsOutOfStorageExample();
                                dcsStorageExample.createCriteria().andSernrEqualTo(vin)
                                        .andDataIdIn(dataIds);
                                List<WmsOutOfStorage> outOfStorages = wmsOutOfStorageMapper.selectByExample(dcsStorageExample);
                                if (CollectionUtils.isNotEmpty(outOfStorages)) {
                                    WmsOutOfStorage v = outOfStorages.get(0);
                                    v.setGmtUpdate(new Date());
                                    v.setZmsg(emsg);
                                    v.setSendStatus(SendStatusEnum.SEND_FAILED.getValue());
                                    wmsOutOfStorageMapper.updateByPrimaryKeySelective(v);
                                    //先查询表中有无数据
                                    WmsOutOfStorageExcpExample excpExample = new WmsOutOfStorageExcpExample();
                                    excpExample.createCriteria().andDataIdEqualTo(v.getDataId());
                                    List<WmsOutOfStorageExcp> wmsOutOfStorageExcps = wmsOutOfStorageExcpMapper.selectByExample(excpExample);
                                    //更新dcs返回结果
                                    updateOutOfStorageAndExcp(v, wmsOutOfStorageExcps, emsg);
                                }
                            }
                        } else {
                            //如果异常明细为空的时候 同步所有的都为异常状态
                            wmsOutOfStorageList.forEach(v -> {
                                v.setGmtUpdate(new Date());
                                v.setZmsg("DCS处理异常");
                                v.setSendStatus(SendStatusEnum.SEND_FAILED.getValue());
                                wmsOutOfStorageMapper.updateByPrimaryKeySelective(v);
                                //先查询表中有无数据
                                WmsOutOfStorageExcpExample excpExample = new WmsOutOfStorageExcpExample();
                                excpExample.createCriteria().andDataIdEqualTo(v.getDataId());
                                List<WmsOutOfStorageExcp> wmsOutOfStorageExcps = wmsOutOfStorageExcpMapper.selectByExample(excpExample);
                                //更新dcs返回结果
                                updateOutOfStorageAndExcp(v, wmsOutOfStorageExcps, "DCS处理异常");
                            });
                        }
                        //throw new BusinessException("同步DCS接口异常!");
                    }
                    if ("S".equals(returnCode_str)) {
                        //成功 --发送的列表全部更新为成功
                        wmsOutOfStorageList.forEach((WmsOutOfStorage v) -> {
                            v.setGmtUpdate(new Date());
                            v.setZmsg("同步DCS接口成功");
                            v.setSendStatus(SendStatusEnum.SEND_SUCCESS.getValue());
                            wmsOutOfStorageMapper.updateByPrimaryKeySelective(v);
                            //先查询表中有无数据
                            WmsOutOfStorageExcpExample excpExample = new WmsOutOfStorageExcpExample();
                            excpExample.createCriteria().andDataIdEqualTo(v.getDataId());
                            excpExample.setOrderByClause("id desc");
                            List<WmsOutOfStorageExcp> wmsOutOfStorageExcps = wmsOutOfStorageExcpMapper.selectByExample(excpExample);
                            if (CollectionUtils.isNotEmpty(wmsOutOfStorageExcps)) {
                                //增加调用次数
                                WmsOutOfStorageExcp wmsOutOfStorageExcp = wmsOutOfStorageExcps.get(0);
                                if (wmsOutOfStorageExcp.getSendDcsCount() < TOTAL_COUNT) {
                                    wmsOutOfStorageExcp.setSendDcsCount(wmsOutOfStorageExcp.getSendDcsCount() + 1);
                                }
                                wmsOutOfStorageExcp.setZmsg("第" + wmsOutOfStorageExcp.getSendDcsCount() + "次同步DCS接口成功");
                                wmsOutOfStorageExcp.setDcsSendStatus(SendStatusEnum.SEND_SUCCESS.getValue());
                                wmsOutOfStorageExcp.setGmtUpdate(new Date());
                                wmsOutOfStorageExcp.setDcsFinalStatus(SendStatusEnum.SEND_SUCCESS.getValue());
                                wmsOutOfStorageExcpMapper.updateByPrimaryKeySelective(wmsOutOfStorageExcp);
                            }
                        });
                    }
                }
            }
        }
    }

    /**
     * 更新异常及接口表结果
     *
     * @param v                    参数
     * @param wmsOutOfStorageExcps 异常的数据
     */
    private void updateOutOfStorageAndExcp(WmsOutOfStorage v, List<WmsOutOfStorageExcp> wmsOutOfStorageExcps, String msg) {
        if (CollectionUtils.isEmpty(wmsOutOfStorageExcps)) {
            //往接口异常表里写入数据
            WmsOutOfStorageExcp wmsOutOfStorageExcp = new WmsOutOfStorageExcp();
            BeanUtils.copyProperties(v, wmsOutOfStorageExcp);
            wmsOutOfStorageExcp.setSendDcsCount(1);
            wmsOutOfStorageExcp.setZmsg(msg);
            wmsOutOfStorageExcp.setDcsSendStatus(SendStatusEnum.SEND_FAILED.getValue());
            wmsOutOfStorageExcp.setSendSapCount(1);
            wmsOutOfStorageExcp.setZmsgSap(v.getZmsgSap());
            wmsOutOfStorageExcp.setSendStatusSap(v.getSendStatusSap());
            wmsOutOfStorageExcp.setDataId(v.getDataId());//关联对象
            wmsOutOfStorageExcp.setDcsSendStatus(SendStatusEnum.SEND_FAILED.getValue());
            wmsOutOfStorageExcpMapper.insertSelective(wmsOutOfStorageExcp);
        } else {
            WmsOutOfStorageExcp wmsOutOfStorageExcp = wmsOutOfStorageExcps.get(0);
            if (wmsOutOfStorageExcp.getSendDcsCount() <= TOTAL_COUNT) {
                //增加调用次数
                wmsOutOfStorageExcp.setDcsSendStatus(SendStatusEnum.SEND_FAILED.getValue());
                wmsOutOfStorageExcp.setGmtUpdate(new Date());
                if (wmsOutOfStorageExcp.getSendDcsCount() == TOTAL_COUNT) {//已经五次
                    wmsOutOfStorageExcp.setDcsFinalStatus(SendStatusEnum.SEND_FAILED.getValue());
                } else {
                    wmsOutOfStorageExcp.setSendDcsCount(wmsOutOfStorageExcp.getSendDcsCount() + 1);
                }
                wmsOutOfStorageExcp.setZmsg(msg);
                wmsOutOfStorageExcpMapper.updateByPrimaryKeySelective(wmsOutOfStorageExcp);
            }
        }
    }

    /**
     * 交接单webservice 接口:   http://58.144.142.90:50000/dir/wsdl?p=sa/54b25fdde2a33089b0d06f10bc87921d
     *
     * @return
     * @throws Exception
     */
    @Override
    public void saveDlvBillInfoImport(List<WmsHandoverOrder> handoverOrderList) throws Exception {
        LOGGER.info("WmsJmDcsServiceImpl.saveDlvBillInfoImport param{}", handoverOrderList);
        //加入spring的上下文
        //SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
        SimpleDateFormat sdf_1 = new SimpleDateFormat("yyyy/MM/dd");
        StringBuilder soapXmlBuf = new StringBuilder();
        //xml头
        soapXmlBuf.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ext=\"http://externalInterface.dms.infodms.com\" xmlns:beam=\"http://beam.externalInterface.dms.infodms.com\">")
                .append("<soapenv:Header/>")
                .append("<soapenv:Body>")
                .append("<ext:excuteService>")
                .append("<ext:pos>")
                .append("<beam:dmsHeader>")
                .append("<beam:BUSID>" + handoverOrderList.get(0).getDataId() + "</beam:BUSID>")//业务id
                .append("<beam:DTSEND>" + sdf_1.format(new Date()) + "</beam:DTSEND>")//发送时间
                .append("<beam:FREEUSE>" + "" + "</beam:FREEUSE>")//备用字段
                .append("<beam:MSGID>" + handoverOrderList.get(0).getDataId() + "</beam:MSGID>")//消息id
                .append("<beam:RECEIVER>" + WmsWebserviceReceiverAndSenderEnum.RECEIVER_DCS.getText() + "</beam:RECEIVER>")//接收
                .append("<beam:SENDER>" + WmsWebserviceReceiverAndSenderEnum.SENDER.getText() + "</beam:SENDER>")//发送方
                .append("<beam:TLGID>" + WmsWebserviceInterfaceEnum.HANDOVER_DCS.getValue() + "</beam:TLGID>")//接口id
                .append("<beam:TLGNAME>" + WmsWebserviceInterfaceEnum.HANDOVER_DCS.getText() + "</beam:TLGNAME>")//接口名称
                .append("</beam:dmsHeader>")
                .append("<beam:values>");

        //参数拼接
        for (WmsHandoverOrder wmsHandoverOrder : handoverOrderList) {
            if (Objects.equals(wmsHandoverOrder.getMbdat(), null)) {
                throw new BusinessException("出入库日期为空!");
            }
            if (StringUtils.isBlank(wmsHandoverOrder.getZdoc())) {
                throw new BusinessException("交接单号为空");
            }
            if (StringUtils.isBlank(wmsHandoverOrder.getGbno())) {
                throw new BusinessException("组板号为空");
            }
            if (StringUtils.isBlank(wmsHandoverOrder.getMatnr())) {
                throw new BusinessException("物料代码为空");
            }
            if (StringUtils.isBlank(wmsHandoverOrder.getVbeln())) {
                throw new BusinessException("订单号为空");
            }
            if (StringUtils.isBlank(wmsHandoverOrder.getSernr())) {
                throw new BusinessException("原车架号为空");
            }
            soapXmlBuf.append("<ext:item>")
                    .append("<beam:BILL_DATE>" + sdf_1.format(wmsHandoverOrder.getMbdat()) + "</beam:BILL_DATE>")//交接日期
                    .append("<beam:BILL_NO>" + wmsHandoverOrder.getZdoc() + "</beam:BILL_NO>")//交接单号
                    .append("<beam:BO_NO>" + wmsHandoverOrder.getGbno() + "</beam:BO_NO>")//组板单号
                    .append("<beam:COLOR_NAME>" + wmsHandoverOrder.getZcol() + "</beam:COLOR_NAME>")//颜色
                    .append("<beam:FREEUSE1>" + "" + "</beam:FREEUSE1>")
                    .append("<beam:FREEUSE2>" + "" + "</beam:FREEUSE2>")
                    .append("<beam:FREEUSE3>" + "" + "</beam:FREEUSE3>")
                    .append("<beam:FREEUSE4>" + "" + "</beam:FREEUSE4>")
                    .append("<beam:FREEUSE5>" + "" + "</beam:FREEUSE5>")
                    .append("<beam:MATERIAL_CODE>" + wmsHandoverOrder.getMatnr() + "</beam:MATERIAL_CODE>")//物料代码
                    .append("<beam:MODEL_NAME>" + wmsHandoverOrder.getZmode() + "</beam:MODEL_NAME>")//车型
                    .append("<beam:NEW_VIN>" + (StringUtils.isBlank(wmsHandoverOrder.getZsernr()) ? "" : wmsHandoverOrder.getZsernr()) + "</beam:NEW_VIN>")//替换车架号
                    .append("<beam:ORDER_NO>" + wmsHandoverOrder.getVbeln() + "</beam:ORDER_NO>")//订单号
                    .append("<beam:PACKGE_NAME>" + wmsHandoverOrder.getZset() + "</beam:PACKGE_NAME>")//配置
                    .append("<beam:VIN>" + wmsHandoverOrder.getSernr() + "</beam:VIN>")//原车架号
                    .append("</ext:item>");
        }
        soapXmlBuf.append("</beam:values>")
                .append("</ext:pos>")
                .append("</ext:excuteService>")
                .append("</soapenv:Body>")
                .append("</soapenv:Envelope>");
        String soapUrl = "http://" + dcsHost + "/XISOAPAdapter/MessageServlet?senderParty=&senderService=BC_WMS&receiverParty=&receiverService=&interface=SI_WMS2DCS_DlvBillInfoImport&interfaceNamespace=http://zjunma.com/TRAUM/WMS/ALL";
        String soapHost = dcsHost;
        String soapAction = "http://sap.com/xi/WebService/soap/1.1";
        System.err.println(soapXmlBuf.toString());
        LOGGER.info("交接单dcs接口参数:", soapXmlBuf.toString());
        String result = WebServiceSoapUtils.postSoapToPi(soapUrl, soapHost, soapXmlBuf.toString(), soapAction, username, password);
        String xmlResult = StringEscapeUtils.unescapeHtml3(result);
        LOGGER.info("交接单dcs接口结果:", xmlResult);
        System.out.println(xmlResult);
        //记录日志
        String finalXmlResult = xmlResult;
        Runnable runnable = () -> {
            WmsDcsLogWithBLOBs log = new WmsDcsLogWithBLOBs();
            log.setParam(soapXmlBuf.toString());
            log.setMsgHead(null);
            log.setSendType("OUT");
            log.setMsgBody(finalXmlResult);
            log.setGmtCreate(new Date());
            log.setGmtUpdate(new Date());
            log.setUrl("WmsJmDcsServiceImpl.saveDlvBillInfoImport");
            wmsDcsLogMapper.insertSelective(log);
            LOGGER.info("WmsJmDcsServiceImpl.saveDlvBillInfoImport  保存dcs交接单发送dcs日志成功");
        };
        new Thread(runnable).start();
        //解析xml
        if (StringUtils.isNotBlank(xmlResult)) {
            int startIndex = xmlResult.lastIndexOf("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
            int lastIndex = xmlResult.lastIndexOf("</ns0:excuteServiceReturn></ns0:excuteServiceResponse></SOAP:Body></SOAP:Envelope>");
            if (!Objects.equals(startIndex, -1) && !Objects.equals(lastIndex, -1)) {
                xmlResult = xmlResult.substring(startIndex, lastIndex);
                Map<String, Object> objectMap = XmlParseUtils.xml2map(xmlResult);
                //获取返回结果
                String json = new Gson().toJson(objectMap);
                JSONObject jsonObject3 = JSONObject.parseObject(json);
                String code_str = jsonObject3.getString("returnCode");
                JSONObject jsonObject4 = JSONObject.parseObject(code_str);
                String returnCode_str = jsonObject4.getString("returnCode");
                if (StringUtils.isNotBlank(returnCode_str)) {
                    if ("E".equals(returnCode_str)) {
                        //错误
                        String error_str = jsonObject3.getString("errorDetails");
                        if (StringUtils.isNotBlank(error_str)) {
                            if (!error_str.startsWith("[")) {
                                error_str = "[" + error_str + "]";
                            }
                            JSONArray jsonArray = JSONArray.parseArray(error_str);
                            for (WmsHandoverOrder order : handoverOrderList) {
                                for (int i = 0, j = jsonArray.size(); i < j; i++) {
                                    JSONObject jsonObject6 = JSONObject.parseObject(jsonArray.get(i).toString());
                                    String em_str = jsonObject6.getString("eMsg");
                                    JSONObject jsonObject7 = JSONObject.parseObject(em_str);
                                    String emsg = jsonObject7.getString("eMsg");//错误日志
                                    String vin_str = jsonObject6.getString("VIN");
                                    JSONObject jsonObject8 = JSONObject.parseObject(vin_str);
                                    String vin = jsonObject8.getString("VIN");//车架号
                                    //更新交接单接口表中数据
                                    if (StringUtils.isNotBlank(order.getSernr())
                                            && StringUtils.isNotBlank(vin)) {
                                        if (order.getSernr().equals(vin)) {
                                            //找到对应的车架号更新异常信息
                                            order.setResultMsgDcs(emsg);
                                        }
                                    }
                                }
                                order.setGmtUpdate(new Date());
                                order.setSendStatus(SendStatusEnum.SEND_FAILED.getValue());
                                wmsHandoverOrderMapper.updateByPrimaryKeySelective(order);

                                //查询接口异常表
                                updateOrderOutExcpForDcs(order);

                            }

                        } else {
                            //没有返回明细--所有的都返回失败
                            String returnMsg = jsonObject3.getString("returnMsg");
                            JSONObject msg_obj = JSONObject.parseObject(returnMsg);
                            String msg = msg_obj.getString("returnMsg");
                            for (WmsHandoverOrder order : handoverOrderList) {
                                order.setGmtUpdate(new Date());
                                order.setResultMsgDcs(msg);
                                order.setSendStatus(SendStatusEnum.SEND_FAILED.getValue());
                                wmsHandoverOrderMapper.updateByPrimaryKeySelective(order);
                                //查询接口异常表
                                updateOrderOutExcpForDcs(order);
                            }

                        }
                    }
                    if ("S".equals(returnCode_str)) {
                        //成功
                        handoverOrderList.forEach((WmsHandoverOrder v) -> {
                            v.setGmtUpdate(new Date());
                            v.setResultMsgDcs("同步DCS接口成功");
                            v.setSendStatus(SendStatusEnum.SEND_SUCCESS.getValue());
                            wmsHandoverOrderMapper.updateByPrimaryKeySelective(v);
                            //查询接口异常表
                            WmsHandoverOrderExcpExample excpExample = new WmsHandoverOrderExcpExample();
                            excpExample.createCriteria().andDataIdEqualTo(v.getDataId());
                            List<WmsHandoverOrderExcp> wmsHandoverOrderExcps = wmsHandoverOrderExcpMapper.selectByExample(excpExample);
                            if (CollectionUtils.isNotEmpty(wmsHandoverOrderExcps)) {
                                WmsHandoverOrderExcp wmsHandoverOrderExcp = wmsHandoverOrderExcps.get(0);
                                //写入成功
                                wmsHandoverOrderExcp.setResultMsgDcs("第" + wmsHandoverOrderExcp.getSendCountDcs() + "次同步DCS接口成功");
                                wmsHandoverOrderExcp.setFinalSendStatusDcs(SendStatusEnum.SEND_SUCCESS.getValue());
                                wmsHandoverOrderExcp.setGmtUpdate(new Date());
                                wmsHandoverOrderExcp.setSendStatus(SendStatusEnum.SEND_SUCCESS.getValue());
                                wmsHandoverOrderExcpMapper.updateByPrimaryKeySelective(wmsHandoverOrderExcp);
                            }
                        });
                    }
                }
            }
        }
    }

    /**
     * 更新异常接口表数据
     *
     * @param order 订单
     */
    private void updateOrderOutExcpForDcs(WmsHandoverOrder order) {
        WmsHandoverOrderExcpExample excpExample = new WmsHandoverOrderExcpExample();
        excpExample.createCriteria().andDataIdEqualTo(order.getDataId());
        List<WmsHandoverOrderExcp> wmsHandoverOrderExcps = wmsHandoverOrderExcpMapper.selectByExample(excpExample);
        if (CollectionUtils.isEmpty(wmsHandoverOrderExcps)) {
            //往接口异常表里写入数据,
            WmsHandoverOrderExcp handoverOrderExcp = new WmsHandoverOrderExcp();
            BeanUtils.copyProperties(order, handoverOrderExcp);
            handoverOrderExcp.setSendCountDcs(1);
            handoverOrderExcp.setResultMsgDcs(order.getResultMsgDcs());
            handoverOrderExcp.setSendStatus(SendStatusEnum.SEND_FAILED.getValue());
            handoverOrderExcp.setSendCountSap(1);
            handoverOrderExcp.setSendStatusSap(order.getSendStatusSap());
            handoverOrderExcp.setResultMsgSap(order.getResultMsgSap());
            handoverOrderExcp.setSendStatusCrm(order.getSendStatusCrm());
            handoverOrderExcp.setSendCountCrm(1);
            handoverOrderExcp.setResultMsgCrm(order.getResultMsgCrm());
            handoverOrderExcp.setSendStatusTms(order.getSendStatusTms());
            handoverOrderExcp.setSendCountTms(1);
            handoverOrderExcp.setResultMsgTms(order.getResultMsgTms());
            handoverOrderExcp.setGmtUpdate(new Date());
            handoverOrderExcp.setDataId(order.getDataId());
            wmsHandoverOrderExcpMapper.insertSelective(handoverOrderExcp);
        } else {
            WmsHandoverOrderExcp wmsHandoverOrderExcp = wmsHandoverOrderExcps.get(0);
            //增加调用次数
            if (wmsHandoverOrderExcp.getSendCountDcs() <= TOTAL_COUNT) {
                wmsHandoverOrderExcp.setSendStatus(SendStatusEnum.SEND_FAILED.getValue());
                wmsHandoverOrderExcp.setGmtUpdate(new Date());
                if (wmsHandoverOrderExcp.getSendCountDcs() == TOTAL_COUNT) {//最后一次
                    wmsHandoverOrderExcp.setFinalSendStatusDcs(SendStatusEnum.SEND_FAILED.getValue());
                } else {
                    wmsHandoverOrderExcp.setSendCountDcs(wmsHandoverOrderExcp.getSendCountDcs() + 1);
                }
                wmsHandoverOrderExcp.setResultMsgDcs(order.getResultMsgDcs());
                wmsHandoverOrderExcpMapper.updateByPrimaryKeySelective(wmsHandoverOrderExcp);
            }
        }
    }

    /**
     * 发运计划驳回:
     */
    @Override
    public void updateBillCancelAction(WmsShipmentPlanCancel wmsShipmentPlanCancel) throws Exception {
        LOGGER.info("WmsJmDcsServiceImpl.updateBillCancelAction param{}", wmsShipmentPlanCancel);
        //加入spring的上下文
        //SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        StringBuilder soapXmlBuf = new StringBuilder();
        if (Objects.equals(wmsShipmentPlanCancel.getPbBackQuantity(), null)) {
            throw new BusinessException("取消数量为空!");
        }
        if (StringUtils.isBlank(wmsShipmentPlanCancel.getPbGroupBoardNo())) {
            throw new BusinessException("组板号为空");
        }
        if (StringUtils.isBlank(wmsShipmentPlanCancel.getPbMaterialCode())) {
            throw new BusinessException("物料代码为空");
        }
        if (StringUtils.isBlank(wmsShipmentPlanCancel.getPbOrderNo())) {
            throw new BusinessException("订单号为空");
        }
        //xml头
        soapXmlBuf.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ext=\"http://externalInterface.dms.infodms.com\" xmlns:beam=\"http://beam.externalInterface.dms.infodms.com\">")
                .append("<soapenv:Header/>")
                .append("<soapenv:Body>")
                .append("<ext:excuteService>")
                .append("<ext:pos>")
                .append("<beam:dmsHeader>")
                .append("<beam:BUSID>" + wmsShipmentPlanCancel.getId() + "</beam:BUSID>")//业务id
                .append("<beam:DTSEND>" + sdf.format(new Date()) + "</beam:DTSEND>")//发送时间
                .append("<beam:FREEUSE>" + "" + "</beam:FREEUSE>")//备用字段
                .append("<beam:MSGID>" + wmsShipmentPlanCancel.getId() + "</beam:MSGID>")//消息id
                .append("<beam:RECEIVER>" + WmsWebserviceReceiverAndSenderEnum.RECEIVER_DCS.getText() + "</beam:RECEIVER>")//接收
                .append("<beam:SENDER>" + WmsWebserviceReceiverAndSenderEnum.SENDER.getText() + "</beam:SENDER>")//发送方
                .append("<beam:TLGID>" + WmsWebserviceInterfaceEnum.BILLCANCEL_DCS.getValue() + "</beam:TLGID>")//接口id
                .append("<beam:TLGNAME>" + WmsWebserviceInterfaceEnum.BILLCANCEL_DCS.getText() + "</beam:TLGNAME>")//接口名称
                .append("</beam:dmsHeader>")
                .append("<beam:values>");

        //参数拼接
        soapXmlBuf.append("<ext:item>")
                .append("<beam:BO_NO>" + wmsShipmentPlanCancel.getPbGroupBoardNo() + "</beam:BO_NO>")//组板号
                .append("<beam:CANCEL_DATE>" + sdf.format(wmsShipmentPlanCancel.getPbBackTime()) + "</beam:CANCEL_DATE>")//驳回日期
                .append("<beam:CANCEL_NUM>" + wmsShipmentPlanCancel.getPbBackQuantity() + "</beam:CANCEL_NUM>")//取消数量
                .append("<beam:FREEUSE1>" + "" + "</beam:FREEUSE1>\n")
                .append("<beam:FREEUSE2>" + "" + "</beam:FREEUSE2>\n")
                .append("<beam:FREEUSE3>" + "" + "</beam:FREEUSE3>\n")
                .append("<beam:FREEUSE4>" + "" + "</beam:FREEUSE4>\n")
                .append("<beam:FREEUSE5>" + "" + "</beam:FREEUSE5>\n")
                .append("<beam:MATERIAL_CODE>" + wmsShipmentPlanCancel.getPbMaterialCode() + "</beam:MATERIAL_CODE>")//物料代码
                .append("<beam:ORDER_NO>" + wmsShipmentPlanCancel.getPbOrderNo() + "</beam:ORDER_NO>")//订单号
                .append("</ext:item>");
        soapXmlBuf.append("</beam:values>")
                .append("</ext:pos>")
                .append("</ext:excuteService>")
                .append("</soapenv:Body>")
                .append("</soapenv:Envelope>");
        String soapUrl = "http://" + dcsHost + "/XISOAPAdapter/MessageServlet?senderParty=&senderService=BC_WMS&receiverParty=&receiverService=&interface=SI_WMS2DCS_BillCancelAction&interfaceNamespace=http://zjunma.com/TRAUM/WMS/ALL";
        String soapHost = dcsHost;
        String soapAction = "http://sap.com/xi/WebService/soap/1.1";
        System.err.println(soapXmlBuf.toString());
        LOGGER.info("发运计划驳回调用dcs接口参数:", soapXmlBuf.toString());
        String result = WebServiceSoapUtils.postSoapToPi(soapUrl, soapHost, soapXmlBuf.toString(), soapAction, username, password);
        String xmlResult = StringEscapeUtils.unescapeHtml3(result);
        LOGGER.info("发运计划驳回调用dcs接口结果:", xmlResult);
        System.out.println(xmlResult);
        //记录日志
        String finalXmlResult = xmlResult;
        Runnable runnable = () -> {
            WmsDcsLogWithBLOBs log = new WmsDcsLogWithBLOBs();
            log.setParam(soapXmlBuf.toString());
            log.setMsgHead(null);
            log.setSendType("OUT");
            log.setMsgBody(finalXmlResult);
            log.setGmtCreate(new Date());
            log.setGmtUpdate(new Date());
            log.setUrl("WmsJmDcsServiceImpl.updateBillCancelAction");
            wmsDcsLogMapper.insertSelective(log);
            LOGGER.info("WmsJmDcsServiceImpl.updateBillCancelAction  保存dcs发运计划驳回发送dcs日志成功");
        };
        new Thread(runnable).start();
        //解析xml
        if (StringUtils.isNotBlank(xmlResult)) {
            int startIndex = xmlResult.lastIndexOf("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
            int lastIndex = xmlResult.lastIndexOf("</ns0:excuteServiceReturn></ns0:excuteServiceResponse></SOAP:Body></SOAP:Envelope>");
            if (!Objects.equals(startIndex, -1) && !Objects.equals(lastIndex, -1)) {
                xmlResult = xmlResult.substring(startIndex, lastIndex);

                Map<String, Object> objectMap = XmlParseUtils.xml2map(xmlResult);
                //获取返回结果
                String json = new Gson().toJson(objectMap);
                JSONObject jsonObject3 = JSONObject.parseObject(json);
                String code_str = jsonObject3.getString("returnCode");
                JSONObject jsonObject4 = JSONObject.parseObject(code_str);
                String returnCode_str = jsonObject4.getString("returnCode");
                if (StringUtils.isNotBlank(returnCode_str)) {
                    if ("E".equals(returnCode_str)) {
                        //错误
                        String error_str = jsonObject3.getString("errorDetails");
                        if (StringUtils.isNotBlank(error_str)) {
                            if (!error_str.startsWith("[")) {
                                error_str = "[" + error_str + "]";
                            }
                            JSONArray jsonArray = JSONArray.parseArray(error_str);
                            for (Object o : jsonArray) {
                                JSONObject jsonObject6 = JSONObject.parseObject(o.toString());
                                String em_str = jsonObject6.getString("eMsg");
                                JSONObject jsonObject7 = JSONObject.parseObject(em_str);
                                String emsg = jsonObject7.getString("eMsg");//错误日志
                                String bo_str = jsonObject6.getString("BO_NO");
                                JSONObject jsonObject8 = JSONObject.parseObject(bo_str);
                                String bo_no = jsonObject8.getString("BO_NO");//组板单号
                                String or_str = jsonObject6.getString("ORDER_NO");
                                JSONObject jsonObject9 = JSONObject.parseObject(or_str);
                                String order_no = jsonObject9.getString("ORDER_NO");//订单号
                                String ma_str = jsonObject6.getString("MATERIAL_CODE");
                                JSONObject jsonObject10 = JSONObject.parseObject(ma_str);
                                String material_code = jsonObject10.getString("MATERIAL_CODE");//物料编号
                                //更新发运计划接口表中数据
                                WmsShipmentPlanCancelExample shipmentPlanCancelExample = new WmsShipmentPlanCancelExample();
                                //过滤已经处理成功的数据
                                shipmentPlanCancelExample.createCriteria()
                                        .andPbGroupBoardNoEqualTo(bo_no)
                                        .andPbOrderNoEqualTo(order_no)
                                        .andPbMaterialCodeEqualTo(material_code)
                                        .andSendStatusEqualTo(SendStatusEnum.SEND_INIT.getValue());
                                List<WmsShipmentPlanCancel> planCancels = wmsShipmentPlanCancelMapper.selectByExample(shipmentPlanCancelExample);
                                if (CollectionUtils.isNotEmpty(planCancels)) {
                                    WmsShipmentPlanCancel planCancel = planCancels.get(0);
                                    planCancel.setGmtUpdate(new Date());
                                    planCancel.setSendStatus(SendStatusEnum.SEND_FAILED.getValue());
                                    planCancel.setMsgDcs(emsg);
                                    wmsShipmentPlanCancelMapper.updateByPrimaryKeySelective(planCancel);
                                    //更新异常接口表
                                    WmsShipmentCancelExcpExample excpExample = new WmsShipmentCancelExcpExample();
                                    excpExample.createCriteria().andDataIdEqualTo(wmsShipmentPlanCancel.getId());
                                    List<WmsShipmentCancelExcp> wmsShipmentCancelExcps = wmsShipmentCancelExcpMapper.selectByExample(excpExample);
                                    if (CollectionUtils.isNotEmpty(wmsShipmentCancelExcps)) {
                                        //次数加1
                                        WmsShipmentCancelExcp wmsShipmentCancelExcp = wmsShipmentCancelExcps.get(0);
                                        if (wmsShipmentCancelExcp.getSendDcsCount() <= TOTAL_COUNT) {
                                            wmsShipmentCancelExcp.setSendStatus(SendStatusEnum.SEND_FAILED.getValue());
                                            wmsShipmentCancelExcp.setGmtUpdate(new Date());
                                            wmsShipmentCancelExcp.setMsgDcs(emsg);
                                            if (wmsShipmentCancelExcp.getSendDcsCount() == TOTAL_COUNT) {
                                                wmsShipmentCancelExcp.setDcsFinalStatus(SendStatusEnum.SEND_FAILED.getValue());
                                            } else {
                                                wmsShipmentCancelExcp.setSendDcsCount(wmsShipmentCancelExcp.getSendDcsCount() + 1);
                                            }
                                            wmsShipmentCancelExcpMapper.updateByPrimaryKeySelective(wmsShipmentCancelExcp);
                                        }

                                    } else {
                                        //插入到接口异常表中
                                        WmsShipmentCancelExcp wmsShipmentCancelExcp = new WmsShipmentCancelExcp();
                                        BeanUtils.copyProperties(planCancels.get(0), wmsShipmentCancelExcp);
                                        wmsShipmentCancelExcp.setSendDcsCount(1);
                                        wmsShipmentCancelExcp.setSendStatus(SendStatusEnum.SEND_FAILED.getValue());
                                        wmsShipmentCancelExcp.setDataId(planCancels.get(0).getId());
                                        wmsShipmentCancelExcp.setGmtCreate(new Date());
                                        wmsShipmentCancelExcp.setGmtUpdate(new Date());
                                        wmsShipmentCancelExcp.setMsgDcs(emsg);
                                        wmsShipmentCancelExcpMapper.insertSelective(wmsShipmentCancelExcp);
                                    }
                                }
                            }
                            //throw new BusinessException("同步DCS接口异常!");
                        }
                    }
                    if ("S".equals(returnCode_str)) {
                        //成功
                        wmsShipmentPlanCancel.setGmtUpdate(new Date());
                        wmsShipmentPlanCancel.setMsgDcs("同步DCS接口成功");
                        wmsShipmentPlanCancel.setSendStatus(SendStatusEnum.SEND_SUCCESS.getValue());
                        wmsShipmentPlanCancelMapper.updateByPrimaryKeySelective(wmsShipmentPlanCancel);
                        //更新异常接口表
                        WmsShipmentCancelExcpExample excpExample = new WmsShipmentCancelExcpExample();
                        excpExample.createCriteria().andDataIdEqualTo(wmsShipmentPlanCancel.getId());
                        List<WmsShipmentCancelExcp> wmsShipmentCancelExcps = wmsShipmentCancelExcpMapper.selectByExample(excpExample);
                        if (CollectionUtils.isNotEmpty(wmsShipmentCancelExcps)) {
                            WmsShipmentCancelExcp wmsShipmentCancelExcp = wmsShipmentCancelExcps.get(0);
                            wmsShipmentCancelExcp.setGmtUpdate(new Date());
                            wmsShipmentCancelExcp.setMsgDcs("第" + wmsShipmentCancelExcp.getSendDcsCount() + "次调用DCS接口成功");
                            wmsShipmentCancelExcp.setSendStatus(SendStatusEnum.SEND_SUCCESS.getValue());
                            wmsShipmentCancelExcp.setDcsFinalStatus(SendStatusEnum.SEND_SUCCESS.getValue());
                            wmsShipmentCancelExcpMapper.updateByPrimaryKeySelective(wmsShipmentCancelExcp);

                        }
                    }
                }
            }
        }
    }
}
